package work.thread_eg.concurrent.lock;


import java.util.concurrent.Semaphore;

/**
 * Semaphore信号量机制
 * 如果线程要访问一个资源就必须先获得信号量。如果信号量内部计数器大于0，信号量减1，然后允许共享这个资源；
 * 否则，如果信号量的计数器等于0，信号量将会把线程置入休眠直至计数器大于0.当信号量使用完时，必须释放
 *
 * 特性
 * 1) 默认是非公平的  可以设置公平 内部是有队列的(AbstractQueuedSynchronizer对象 AQS)
 *    队列是有序的 但是线程调度谁先进队列是不可控制的
 *
 * 用法
 * 1) 限流 : 用于设置多少个线程可以同时执行 比如由100个线程 我可以设置同时运行的线程只有2个
 */
public class SemaphoreTest01 {

    public static void main(String[] args) {

        // 参数是允许的数量
        // 如果参数是2 那么两个线程就会同时执行
        Semaphore s = new Semaphore(1);

        new Thread(()-> {
            try{
                // 阻塞方法 acquire之后由1变成0 其他线程就不能获取了
                // Semaphore的构造函数是2的话 就会减1
                // acquire是获得锁
                s.acquire();
                System.out.println("T1 running...");
                Thread.sleep(200);
                System.out.println("T1 running...");
            }catch (InterruptedException ex) {
                ex.printStackTrace();
            } finally {
                // release()表示 由0变成1 其他线程就能获取了
                // Semaphore使用 release进行释放
                s.release();
            }
        }).start();

        new Thread(()-> {
            try{
                s.acquire();
                System.out.println("T2 running...");
                Thread.sleep(200);
                System.out.println("T2 running...");
            }catch (InterruptedException ex) {
                ex.printStackTrace();
            } finally {
                s.release();
            }
        }).start();

    }
}
